﻿using BCEntity.CRM.CustomerInfo;
using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BCEntity.Sim.Admin.Admin;
using BCEntity.Sim.Company.Department;
using BCEntity.Sim.Admin.StaffOrganizationMappingRecord;
using BCCommon;

namespace BCData.CRM.CustomerInfo
{
    public class CustomerInfoData : ICustomerInfoData
    {
        private IDatabaseContext database;
        const string QUERY = @"SELECT
		    A.CustomerInfoId,
		    A.CompanyId,
		    A.UserName,
		    A.Phone,
		    A.Email,
		    A.Sex,
		    A.ResourceType,
		    A.ProvinceCode,
		    A.ProvinceName,
		    A.CityCode,
		    A.CityName,
		    A.CountyCode,
		    A.CountyName,
		    A.Address,
		    A.ReceptionTimes,
		    A.CustomerLevel,
		    A.CustomerCategory,
		    A.PreestimateBookTime,
		    A.IdentityCardNo,
		    A.Birthday,
		    A.CustomerType,
		    A.CustomerGrade,
		    A.CreateTime,
		    A.UpdateTime,
		    A.WeChatNo,
		    A.AdminId,
		    A.AdminFullName,
		    A.IsFill,
		    A.IsGivenUp,
		    A.FillTimes,
		    A.FollowUpTimes,
		    A.BelongStartDate,
		    A.BelongEndDate,
		    A.IsExceedTime,
		    A.VehicleSaleContractNo,
		    A.FillTime,
		    A.Avatar,
		    A.AccountStatus
        FROM
            crm_customerinfo A";

        #region 构造函数
        public CustomerInfoData(IDatabaseContext databaseContext)
        {
            this.database = databaseContext;
        }
        #endregion

        #region InsertAsync
        /// <summary>
        /// 添加新纪录
        /// </summary>
        /// <param name="CustomerInfoEntity"></param>
        /// <returns></returns>
        public async Task<CustomerInfoEntity> InsertAsync(CustomerInfoEntity entity)
        {
            return await this.database.Master.InsertAsync(entity, database.Transaction);
        }
        #endregion


        #region updateAsync
        /// <summary>
        /// 根据主键ID更新记录
        /// </summary>
        /// <param name="CustomerInfoEntity"></param>
        /// <returns></returns>
        public async Task<CustomerInfoEntity> UpdateAsync(CustomerInfoEntity entity)
        {
            return await this.database.Master.UpdateAsync(entity, database.Transaction);
        }
        #endregion 

        #region Delete
        /// <summary>
        /// 删除指定ID的记录
        /// </summary>
        /// <param name="CustomerInfoId"></param>
        /// <returns></returns>
        public async Task<bool> Delete(long customerInfoId)
        {
            string fSql = "DELETE FROM crm_customerinfo WHERE CustomerInfoId =?CustomerInfoId ";
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?CustomerInfoId", customerInfoId, DbType.Int64);
            return await this.database.Master.ExecuteAsync(fSql, parameters,database.Transaction)>0;
        }
        #endregion

        #region GetById
        /// <summary>
        /// 获取指定ID的记录
        /// </summary>
        /// <param name="CustomerInfoId"></param>
        /// <returns></returns>
        public async Task<CustomerInfoEntity> GetByIdAsync(long customerInfoId)
        {
            string fSql = QUERY + " WHERE  A.CustomerInfoId =?CustomerInfoId ";
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?CustomerInfoId", customerInfoId, DbType.Int64); 
            return await this.database.Slave.QueryFirstOrDefaultAsync<CustomerInfoEntity>(fSql, parameters);
        }
        #endregion

        #region GetAll 
        public async Task<IEnumerable<CustomerInfoEntity>> GetAllAsync(int companyId)
        {
            string sql = QUERY + " WHERE  A.CompanyId =?CompanyId ";
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?CompanyId", companyId, DbType.Int64);
            return await this.database.Slave.QueryAsync<CustomerInfoEntity>(sql,parameters);
        }
        #endregion


        #region GetList 
        public async Task<(int, IEnumerable<CustomerInfoEntity>)> GetListAsync(
                    AdminEntity ccAdminEntity,  
                    int companyId,
                    string ccUserName,
                    string ccPhone,
                    string ccResourceType,
                    string ccCustomerType,
                    bool? ccIsFill,
                    string ccProvinceId,
                    string ccCityId,
                    string ccCountyId,
                    int ccPageNo,
                    int ccPageSize)
        {
            string fSql = string.Empty;
            DynamicParameters parameters = new DynamicParameters();
            if (ccAdminEntity.IsSystemAccount)
            {
                fSql = " WHERE 1=1";
            } 
            else
            {
                foreach (var item in GetListAdminId(ccAdminEntity))
                {
                    fSql += item + ",";
                }
                fSql = " WHERE  ADMINID IN ( " + fSql.TrimEnd(',') + " )";
            }

            fSql += string.Format($" AND CompanyId={companyId} ");

            if (!string.IsNullOrEmpty(ccUserName))
            {
                fSql += string.Format(" AND UserName like '%{0}%'", ccUserName);
            }
            if (!string.IsNullOrEmpty(ccPhone))
            {
                fSql += string.Format(" AND phone like '%{0}%'", ccPhone);
            }
            if (!string.IsNullOrEmpty(ccProvinceId))
            {
                fSql += string.Format(" AND provinceid = '{0}'", ccProvinceId);
            }
            if (!string.IsNullOrWhiteSpace(ccCityId))
            {
                fSql += string.Format(" AND cityid = '{0}'", ccCityId);
            }

            if (!string.IsNullOrWhiteSpace(ccCustomerType))
            {
                fSql += string.Format(" AND CustomerType= '{0}'", ccCustomerType);
            }
            if (!string.IsNullOrEmpty(ccResourceType))
            {
                fSql += string.Format(" AND ResourceType= '{0}'", ccResourceType);
            }
            if (ccIsFill != null)
            {
                fSql += string.Format(" AND IsFill = {0}", ccIsFill);
            }
            string fSqlCount = "SELECT COUNT(1) FROM crm_customerinfo " + fSql;

            fSql = QUERY + fSql;

            fSql += string.Format(" limit {0},{1} ", (ccPageNo - 1) * ccPageSize, ccPageSize);

            var fRet = await this.database.Slave.QueryMultipleAsync<CustomerInfoEntity, int>(fSql + "; " + fSqlCount);

            var fDataList = fRet.Item1;
            var fCount = fRet.Item2;

            return (fCount, fDataList.ToList());
        }

        private List<long> GetListAdminId(AdminEntity ccAdminEntity)
        {
            string fSql = "SELECT * FROM department ";
            IEnumerable<DepartmentEntity> fListDepartMent = this.database.Slave.QueryAsync<DepartmentEntity>(fSql).GetAwaiter().GetResult();
            var fDepartmentEntity = fListDepartMent.FirstOrDefault(s => s.PrincipalAdminId == ccAdminEntity.AdminId);

            List<long> fListAdminId = new List<long>();
            if(fDepartmentEntity == null)
            {
                fListAdminId.Add(ccAdminEntity.AdminId);
            }
            else
            {
                fListAdminId = GetListAdminId(GetDepartmentID(fDepartmentEntity, fListDepartMent));
            }
            return fListAdminId;
        }

        private List<int> GetDepartmentID(DepartmentEntity ccDepartmentEntity,IEnumerable<DepartmentEntity> ccListDepartmentEntity)
        {
            List<int> fListDepartmentId = new List<int>();
            fListDepartmentId.Add(ccDepartmentEntity.DepartmentId);
            foreach (var item in ccListDepartmentEntity.Where(s => s.ParentDepartmentId == ccDepartmentEntity.DepartmentId))
            {
                fListDepartmentId.Add(item.DepartmentId);
                foreach (var item2 in ccListDepartmentEntity.Where(s=>s.ParentDepartmentId == item.DepartmentId))
                {
                    fListDepartmentId.Add(item2.DepartmentId);
                    foreach (var item3 in ccListDepartmentEntity.Where(s=>s.ParentDepartmentId == item2.DepartmentId))
                    {
                        fListDepartmentId.Add(item3.DepartmentId);
                        foreach (var item4 in ccListDepartmentEntity.Where(s=>s.ParentDepartmentId == item3.DepartmentId))
                        {
                            fListDepartmentId.Add(item4.DepartmentId);
                        }
                    }
                }
            }
            return fListDepartmentId;
        }

        private List<long> GetListAdminId(IEnumerable<int> ccListDepartmentId)
        {
            string fSql = " SELECT AdminId FROM StaffOrganizationMappingRecord WHERE departmentid IN  ";

            string fStr = string.Empty;
            foreach (var item in ccListDepartmentId)
            {
                fStr += item + ",";
            }
            fStr = "(" + fStr.TrimEnd(',') + ")";
            fSql += fStr;

            IEnumerable<StaffOrganizationMappingRecordEntity> fListDepartMentStaff = this.database.Slave.QueryAsync<StaffOrganizationMappingRecordEntity>(fSql).GetAwaiter().GetResult();
            List<long> ccListAdminId = fListDepartMentStaff.Select(p => p.AdminId).ToList();
            return ccListAdminId;
        }

        #endregion
    }
}
